# 派工算法调用此文件

import sys
sys.path.append('..')
import time
import sys
from datetime import datetime, timedelta
# from base_data_class import Flight, Task
# import utils
from xlrd import open_workbook
import copy
import json
import requests


def getDispatchId(loc_str, dispatch_names):
    # '''
    # 功能：获取指定保障环节的id
    # 输入：loc_str客户基础数据服务器地址，默认值loc_str='112.6.126.153:8060'
    # '''
    # # 如果传入的参数包含ip地址，则从接口中读取数据
    # if utils.hasIP(loc_str):
    #     dispatch_URL = 'http://'+loc_str+'/basedata/dispatch/findAll' #获取保障环节ID
    #     r = requests.get(dispatch_URL)
    #     dispatch_info = r.json()
    # # 否则，从本地文件读取数据
    # elif loc_str[-4:]=='json':   
    #     dispatch_info_file = open(loc_str)
    #     dispatch_info = json.load(dispatch_info_file)

    with open(loc_str, 'r') as f:
        dispatch_info = json.load(f)
        
    dispatch_Ids = []
    for item in dispatch_info:
        if item['name'] in dispatch_names:
            if item['id'] in dispatch_Ids:
                continue
            dispatch_Ids.append(item['id'])
    return dispatch_Ids
      

def screenFlight(flight_data,dispatch_Ids):
    '''
    功能：过滤航班数据和航班任务，将符合条件的航班和不符合条件的航班进行分离
    输入：flight_data所有航班数据
    输入：dispatch_Ids目标航班任务列表
    输出：valid_flights有效航班
    输出：invalid_flights无效航班数据，包括航班号及航班无效原因
    '''
    '''
    航班剔除准则包括：1）航班任务列表为空
                   2）机位数据等字段缺失
                   3）航班任务列表中任务均不在dispatch_Ids中
                   4）到达航班缺失到达时刻
                   5）出发航班缺失出发时刻
                   6）出发航班缺失登机口字段
                   7）航班Id重复
    '''    
    valid_flights = []
    valid_flights_Id = []
    invalid_flights = []

    for item in flight_data:
        if len(item['dispatchTaskList'])==0: # 无任务
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'dispatchTaskList empty'})
            continue
        if item['craftSeat']=='': # 机位数据缺失
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'craftSeat empty'})
            continue
        # 提取航班task列表中的数据
        tasks = []
        task_dispatch_Ids = []
        
        # 到达航班缺失到达时刻
        if item['isArrFlight'] and (item['arrPlanLanding']=='' or 'arrPlanLanding' not in item.keys()):
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'ArrFlight without arrPlanLanding'})
            continue
        # 出发航班缺失出发时刻
        if item['isArrFlight'] is False and ('depPlanTakeOff' not in item.keys() or item['depPlanTakeOff']==''):
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'DepFlight without depPlanTakeOff'})
            continue
        # 出发航班缺失登机口
        if item['isArrFlight'] is False and ('departureGate' not in item.keys() or item['departureGate']==''):
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'DepFlight without departureGate'})
            continue       
        
        # 航班Id重复
        if str(item['id']) in valid_flights_Id:
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'flightId duplicated'})
            continue

        # 机位
        if isinstance(item['craftSeat'], str):
            craft_seat = item['craftSeat']
        else:
            craft_seat = str(int(item['craftSeat']))
        craft_seat = item['craftSeat'].split(',')[0]
        craft_seat = craft_seat.split('(')[0]
        
        # 登机口
        if isinstance(item['departureGate'], str):
            departureGate = item['departureGate']
        else:
            departureGate = str(int(item['departureGate']))
        departureGate = departureGate.split(',')[0]
        departureGate = departureGate.split('(')[0]
        # 为了避免登机口与机位的编号重合，运行时间矩阵中,在登机口前加了前缀'DEP'
        # 若登机口的编号规则变了，需要注释掉下面这一行
        # departureGate = 'DEP'+departureGate

        # 到达口
        arrivalGate=''
        if item['isArrFlight']:
            if item['airlineCn'][0:2]=="东方":
                arrivalGate='A2'
            else:     
                if item['regionName']=='国际':
                    arrivalGate='A1'
                elif item['regionName']=='国内':
                    arrivalGate='A3'
                else:
                    arrivalGate='A3'

        # 校正hasVip和vipCnt数据
        if item['hasVip'] is False:
            item['vipCnt']='0'

        
        for task in item['dispatchTaskList']: # 遍历航班任务列表
            if ('dispatchId' not in task.keys()) or (task['dispatchId'] is None): # 环节Id缺失
                continue
            if ('id' not in task.keys()) or (task['id'] is None): # 任务Id缺失
                continue
            if task['dispatchId'] in task_dispatch_Ids: # 任务重复：同一保障环节出现了两个任务
                continue     

            # 找到在dispatch_ids中的任务
            if task['dispatchId'] in dispatch_Ids or int(task['dispatchId']) in dispatch_Ids:
                task_Id = task['id']
                flight_Id = item['id']
                dispatch_Id = task['dispatchId']
                start_plan_time = task['startPlanTime']+':00'
                end_plan_time = task['endPlanTime']+':00'
                if item['isArrFlight']:
                    startPosition = [0,craft_seat]
                    endPosition = [2,arrivalGate]
                else:
                    startPosition = [1,departureGate]
                    endPosition = [0,craft_seat]
                passengerCnt = int(float(item['passengerCnt']))
                vipCnt = int(float(item['vipCnt']))
                # tasks.append(Task(task_Id,flight_Id,dispatch_Id,start_plan_time,end_plan_time,
                #                   startPosition,endPosition,passengerCnt,vipCnt))
                tasks.append({
                    "task_Id": task_Id,
                    "flight_Id": flight_Id,
                    "dispatch_Id": dispatch_Id,
                    "start_plan_time": start_plan_time,
                    "end_plan_time": end_plan_time,
                    "startPosition": startPosition,
                    "endPosition": endPosition,
                    "passengerCnt": passengerCnt,
                    "vipCnt": vipCnt,
                })
                task_dispatch_Ids.append(task['dispatchId'])

        if not tasks: # 不存在dispatch_ids中的任务
            invalid_flights.append({'flightId':item['id'],
                                    'msg':'no target tasks'})
            continue

        valid_flights.append([str(item['id']), item['isArrFlight'], craft_seat, 
                            departureGate, arrivalGate, item['arrPlanLanding'], 
                            item['depPlanTakeOff'], item['passengerCnt'], item['vipCnt'],
                            copy.deepcopy(tasks), item['flightNo']])
        valid_flights_Id.append(str(item['id']))
    return valid_flights,invalid_flights


def getFlight(valid_flights, t_arrival=5, t_port=35):
    '''
    功能：通过列表格式的航班数据构造航班对象列表
    输入：valid_flights航班数据，每条数据为一个列表，列表中字段见screenFlight函数倒数第三行代码
    输出：航班对象列表，列表中每个元素为Flight对象，其类数据见base_data_class
    '''
    flights = []
    for item in valid_flights:
        flight_Id = item[0] # 航班号
        is_arrive_flight = 1 if item[1] is True else 0 # 是否进港航班  
        passenger_count = int(float(item[7])) # 普通乘客数量
        vip_count = int(float(item[8])) # vip乘客数量

        craft_seat = item[2]
        departure_gate = item[3]
        arrival_gate = item[4]

        # flight_moment:航班进港（对进港航班而言）或出港时刻（对出港航班而言）
        flight_moment = str(item[5]) if is_arrive_flight else str(item[6])
        # flight_moment = utils.time_parse(flight_moment)
        fmt = "%Y-%m-%d %H:%M:%S"
        flight_moment = datetime.strptime(flight_moment, fmt)

        # moment:航班任务起准点
        moment = flight_moment- timedelta(minutes=t_arrival) if is_arrive_flight else flight_moment-timedelta(minutes=t_port)   
        tasks = item[9]
        
        flightNo = item[10]
        
        # flights.append(Flight(flight_Id,is_arrive_flight,flight_moment,
        #                moment,craft_seat,departure_gate,arrival_gate,
        #                passenger_count,vip_count,tasks))
        flights.append({
            "flight_Id": flight_Id,
            "is_arrive_flight": is_arrive_flight,
            "flight_moment": flight_moment,
            "moment": moment,
            "flight_date": flight_moment.date(),
            "craft_seat": craft_seat,
            "departure_gate": departure_gate,
            "arrival_gate": arrival_gate,
            "passenger_count": passenger_count,
            "vip_count": vip_count,
            "tasks": tasks,
            "flightNo": flightNo,
        })
    return flights
    

def parse(batch_dispatch_file_name, dispatch_info_file_name, dispatch_names):
    # 读取本地文件
    with open(batch_dispatch_file_name, 'r') as f:
        dispatch_input = json.load(f)

    dispatch_ids = getDispatchId(dispatch_info_file_name, dispatch_names)

    # 筛选航班数据
    flight_data = dispatch_input['flightDtoList']
    valid_flights, invalid_flights = screenFlight(flight_data, dispatch_ids)

    # 构造航班对象列表
    flights = getFlight(valid_flights)
    # print([len(flight["tasks"]) for flight in flights])

    return flights